package com.dianjing.dianjing.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dianjing.dianjing.dto.input.DemandInput;
import com.dianjing.dianjing.dto.input.InformInput;
import com.dianjing.dianjing.dto.input.PublishInput;
import com.dianjing.dianjing.entity.Demand;
import com.dianjing.dianjing.entity.Inform;
import com.dianjing.dianjing.entity.Order;
import com.dianjing.dianjing.entity.User;
import com.dianjing.dianjing.enums.DemandStateEnum;
import com.dianjing.dianjing.enums.OrderStateEnum;
import com.dianjing.dianjing.enums.UserTypeEnum;
import com.dianjing.dianjing.mapper.DemandMapper;
import com.dianjing.dianjing.service.DemandService;
import com.dianjing.dianjing.service.InformService;
import com.dianjing.dianjing.service.OrderService;
import com.dianjing.dianjing.service.UserService;
import com.dianjing.dianjing.util.DataUtils;
import com.dianjing.dianjing.util.MapUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.Date;
import java.util.List;

/**
 * <p>
 * 需求表 服务实现类
 * </p>
 *
 * @author LBG
 * @since 2022-11-09
 */
@Service
public class DemandServiceImpl extends ServiceImpl<DemandMapper, Demand> implements DemandService {

    @Autowired
    private UserService userService;

    @Autowired
    private OrderService orderService;

    @Autowired
    private InformService informService;
    /**
     * 发布需求
     *
     * @param input
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public DataUtils publishDemand(PublishInput input) {
        Demand map = MapUtil.map(input, Demand.class);
        Long demandUserId = input.getDemandUserId();
        User demandUser = userService.getById(demandUserId);
        if (ObjectUtil.isNotNull(demandUser)) {
            // 将需求方信息放在表单中
            map.setIcon(demandUser.getHeaderUrl());
            map.setPhone(demandUser.getEmail());
            map.setName(demandUser.getNickname());
            map.setPainterId(input.getPainterId());
            map.setDdl(input.getDdl());
        }
        // 如果是状态是待响应，将需求访id置空
        if(map.getState().equals(DemandStateEnum.WAIT_RESPONSE.getState())) {
            map.setPainterId(null);
        }
        this.save(map);
        return DataUtils.ok();
    }

    /**
     * 查看所有需求
     * @return
     */
    @Override
    public DataUtils showAllDemand(DemandInput input) {
        QueryWrapper<Demand> wrapper = new QueryWrapper<>();
        // 需求的类型
        if(ObjectUtil.isNotNull(input.getType())){
            wrapper.lambda().eq(Demand::getType,input.getType());
        }
        // 需求状态
        if(ObjectUtil.isNotNull(input.getState())){
            wrapper.lambda().eq(Demand::getState,input.getState());
        }
        // 需求方id
        if(ObjectUtil.isNotNull(input.getDemandUserId())){
            wrapper.lambda().eq(Demand::getDemandUserId,input.getDemandUserId());
        }
        // 画师id
        if(ObjectUtil.isNotNull(input.getPainterId())){
            wrapper.lambda().eq(Demand::getPainterId,input.getPainterId());
        }
        return DataUtils.ok(this.list(wrapper));
    }

    /**
     * 根据id查询需求详情
     *
     * @param id
     * @return
     */
    @Override
    public DataUtils selectDemandById(Integer id) {
        return DataUtils.ok(this.getById(id));
    }

    /**
     * 需求响应
     *
     * @param demandId
     * @param painterId
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public DataUtils demandRespond(Long demandId, Long painterId) {
        // 画师响应后，相当于画师接收了需求，此时要将需求转订单，且将画师信息放在订单中
        Boolean b = this.painterReceive(painterId, demandId);
        if (b) {
            return DataUtils.ok();
        }else {
            return DataUtils.error("响应失败");
        }
    }

    /**
     * 拒绝需求
     *
     * @param id
     * @return
     */
    @Override
    public DataUtils refuseDemand(Long id) {
        // 更新需求状态
        Demand demand = new Demand();
        demand.setId(id);
        demand.setState(DemandStateEnum.REJECTED.getState());
        this.updateById(demand);
        return DataUtils.ok();
    }

    @Override
    public List<Demand> getUserWaitAccept(Long userId) {
        User user = userService.getById(userId);
        int userType = user.getType();
        QueryWrapper<Demand> wrapper = new QueryWrapper<>();
        if(userType == UserTypeEnum.DEMANDER.getType()) {
            // 当前为需求方
            // 获取需求中的需求方为自己，且状态为“待响应0”与“待接受1”
            wrapper.eq("demand_user_id",user.getId()).and(r->r.eq("state",DemandStateEnum.WAIT_RESPONSE.getState()).or().eq("state",DemandStateEnum.WAIT_ACCEPT.getState()));
            return baseMapper.selectList(wrapper);

        }else if(userType == UserTypeEnum.PAINTER.getType()){
            // 当前为超管
            wrapper.eq("painter_id",user.getId()).eq("state",DemandStateEnum.WAIT_ACCEPT.getState());
            return baseMapper.selectList(wrapper);
        }
        return null;
    }

    @Override
    public Boolean cancelDemand(Long userId, Integer demandId) {
        // 根据需求id获取需求详情
        Demand demand = baseMapper.selectById(demandId);
        // 判断需求数据中的需求方是否与userId相等 && 需求状态是否为 待接受或待响应
        if (demand.getDemandUserId().equals(userId)
                && (demand.getState().equals(DemandStateEnum.WAIT_ACCEPT.getState())
                || demand.getState().equals(DemandStateEnum.WAIT_RESPONSE.getState()))) {
            // 满足取消条件
            demand.setState(DemandStateEnum.CANCELED.getState());
            // 标记需求为“已取消”
            baseMapper.updateById(demand);
            return true;
        }
        return false;
    }

    @Override
    public Boolean painterRefuse(Long userId, Integer demandId) {
        // 画师只能拒绝让自己接受的
        // 根据需求id获取需求详情
        Demand demand = baseMapper.selectById(demandId);
        // 需求状态是待接受，且接受的画师是自己
        if(demand.getState().equals(DemandStateEnum.WAIT_ACCEPT.getState()) && demand.getPainterId().equals(userId) ) {
            demand.setState(DemandStateEnum.REJECTED.getState());
            baseMapper.updateById(demand);
            return true;
        }
        return false;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean painterReceive(Long painterId, Long demandId) {
        // 画师只能接收让自己待接受的或者大厅的
        // 根据需求id获取需求详情
        Demand demand = baseMapper.selectById(demandId);
        // 需求状态是(待接受，且接受的画师是自己)或者大厅的
        Boolean demandIsHall = demand.getState().equals(DemandStateEnum.WAIT_RESPONSE.getState());
        Boolean demandIsSelf = demand.getState().equals(DemandStateEnum.WAIT_ACCEPT.getState()) && demand.getPainterId().equals(painterId);
        if(demandIsHall || demandIsSelf) {
            // 修改原需求表为已接受状态
            demand.setState(DemandStateEnum.ACCEPTED.getState());
            demand.setPainterId(painterId);
            int i = baseMapper.updateById(demand);
            if(i > 0) {
                // 生成订单
                Order order = new Order();
                order.setDemandName(demand.getName());
                order.setDemandIcon(demand.getIcon());

                // 根据画师id，查画师详细信息
                User painter = userService.getById(painterId);
                // 设置画师头像，画师昵称，id
                order.setPainterId(painter.getId());
                order.setPainterName(painter.getNickname());
                order.setPainterIcon(painter.getHeaderUrl());
                order.setTitle(demand.getTitle());
                order.setContent(demand.getContent());
                order.setType(demand.getType());
                order.setPrice(demand.getPrice());
                order.setDdl(demand.getDdl());
                order.setState(OrderStateEnum.WAIT_CREATE.getState());
                order.setDemandUserId(demand.getDemandUserId());
                order.setOpen(0);
                orderService.save(order);

                // 接受响应或画师接受需求方的需求，在这里通知用户
                Inform info = new Inform();
                // 通知人
                info.setNotifierId(order.getPainterId());
                // 被通知人
                info.setNotifiedPartId(order.getDemandUserId());
                // 消息
                info.setContent(String.format("【画师已接单通知】%s用户您好，您的订单“%s”，已被画师接单了！",order.getDemandName(),order.getTitle()));
                info.setCreateTime(new Date());
                informService.save(info);
                return true;
            }

        }
        // 操作失败进行回滚
        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        return false;
    }

    @Override
    public List<Demand> getWaitResponse(Integer type) {
        // 这里没必要判断用户类型，直接返回待响应的数据即可
        QueryWrapper<Demand> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(Demand::getState,DemandStateEnum.WAIT_RESPONSE.getState())
                        .eq(type != null,Demand::getType,type);
        List<Demand> demands = baseMapper.selectList(wrapper);
        return demands;
    }
}
